using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using System.Text;

namespace Universe.Remoting.Extensions
{
    [Serializable]
    public class DeliveryDictionary
    {
        internal Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
        
        public ICollection<string> Keys
        {
            get { return new List<string>(dictionary.Keys); }
        }

        public void Set<T>(string key, T value)
        {
            lock(dictionary)
                dictionary[key] = value;
        }

        public T Get<T>(string key)
        {
            lock (dictionary)
            {
                object raw;
                if (dictionary.TryGetValue(key, out raw) && raw != null)
                {
                    if (!(raw is T))
                        throw new InvalidCastException(
                            "Delivery Dictionary expect value of type " + typeof (T) + ". Containing type is " + raw.GetType() +
                            ". Key is '" + key + "'");

                    return (T) raw;
                }
            }

            return default(T);
        }

    }

    [Serializable]
    public class ContextData: ILogicalThreadAffinative
    {
        public string[] Keys;
        public object[] Values;

        public static ContextData Serialize(DeliveryDictionary dictionary)
        {
            List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
            foreach (KeyValuePair<string, object> pair in dictionary.dictionary)
            {
                if (!string.IsNullOrEmpty(pair.Key) && pair.Value != null)
                    list.Add(pair);
            }

            ContextData ret = new ContextData();
            int count = list.Count;
            ret.Keys = new string[count];
            ret.Values = new object[count];
            for(int i=0; i<count; i++)
            {
                ret.Keys[i] = list[i].Key;
                ret.Values[i] = list[i].Value;
            }

            return ret;
        }

        public DeliveryDictionary Deserialize()
        {
            DeliveryDictionary ret = new DeliveryDictionary();
            if (Keys != null && Values != null && Keys.Length == Values.Length)
            {
                for (int i = 0; i < Keys.Length; i++)
                    ret.dictionary[Keys[i]] = Values[i];
            }

            return ret;
        }

        public static readonly string SlotName = "U_T_D";
    }
}
